package com.hdax.dm.controller;


import cn.hutool.crypto.asymmetric.RSA;
import com.hdax.dm.exceptions.DmException;
import com.hdax.dm.exceptions.constant.ErrConstant;
import com.hdax.dm.service.UserService;
import com.hdax.dm.user.User;
import com.hdax.dm.utils.response.CommonResponse;
import com.hdax.dm.utils.response.ResponseUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;


import java.security.interfaces.RSAPrivateKey;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(path = "/user")
public class UserController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserService userService;
    //token私钥
    private String private_key="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGrRoSzlQMnqVoOAww2CjQsSPhYIohRMqpRCnRK/Qm5ljD2v4zD1Zc3nDiaQY3PunSnrbvv4mHfvtg9PcqATYLem555llht3aElsWfPw3n19x5722GlLEUua96qepl6A/QRvMwkdd79zahhztJHFatVadOs5WZUmA79q6ewYK25+6rA04SRslKdTm6k1L2cRNqZFSMKE/1IqWHU7ezsfRs7xCzacVj5VONpFodVY+4r4BDWd7rulXqwdMKl8Fe7IPcjg9VfJPw8rW9x40xS7b3U/uvRGNbQGrzEZfn49Eb6BCIB4JhR8WOS0H1q2TWf/GDqG2p2gVWayJZYl2k+wZpAgMBAAECggEAT+R4Iava3KBHP5uaO2IRN6qkFRNvOGWjYWHJtxWHvsTOWSQNKJc4UWwZ1NIK79haypmMUuig81261Ihtg/SsuPzoxBg/RS4zeKnwmlMO0nZZcKc5Ue8lLoJk8Fy3p3ckNMrzLErZbj5BN79btdCxgk55UwqgU+FuVW6jVa/XUplH8TcMZqtgYARRXPQ2uEvsIf4uuCyiqE/w2vxLe0uf2wR7TgGIwumKp6v+rE/9/wPGbMhjk6DmoVOP/G9PeJyWTg7bAw9Kdl+d7iP96oVwD3IFzdPGZkMgtd8ROgUm8fEO6Jn1oRYOtzPjtwjoUIEqYwyOSy241J3lqi7n6+e1AQKBgQDxb9SmRrMtG7CEkEHMfV0fSzljhIF9eaPSTOgPdfeh2+HewL5H2qfZoQX58vT1MyDSCbFGrDwwGYybgIgOtlBI1h/HQmFdWmOx0wzvmF5APxlpoiwTjI06Q+yzHyWg3IDWvaswJ3kDqzagY7rDlgxmorxO5szhj28riLPQW6FEOQKBgQDSqPp+3RVMxIzH9YSQtNncPu3ah287MGG6+Su8N4UFWrVvyCdawYn3uhSmEFF3YvByV+ZVLuCa8fYVU7WNyRLUDTMnAmU83dakgmcJZa7wgP6pmV4iDfsaN0bcuwD4ykXmGU6GdPzch5vR+aOzwLMBIivPk6qy9PF9ZAREK/+zsQKBgDljla54e7qrLEg2ag2LdwkrPlbzdjw3H8OrWDXkmpo0w/nI4vH9fYxzhBInuCZYouKKP0NHSX89c3i7Epw8pdTKYP9iPfaMt8nbGuYQ18Z5uTasv8Fd1WwWHTtumekkwNNKfliR6Wf/2JpDWm+HSSdUY2J15hlvmMNGWUeboDexAoGBAIGSOfEKHu3G/yiGlPFEq7PSaQ4+u2XWjmYomIP+Si1O68ZDgCFMZYYfyE+UPeeGzYonEp9WZAQpy0i24jbBdHlFXS8jRA26DSnGo4WeK4n2baz3jnS30LkBQu7FfwWHtJKhAjGlh1pFdswiFlSbs/6AfB4DH71O97I+cHlV7sMhAoGAB/ZIyNjNg6e3NFjxCnhNvtzXNN8fkOob/bGb0Hzcknat13sgQhi9BBB1hLd4yy3FMOs/AWgSaugmnzUUe+obwNhkEDsy89MLILgaseC/JYj4391HuLOY8Kip3psV53Rhr68ndNKs6dhahchH9kKdLc8rszuo9I/mt9QgXUTNk6c=";
        //创建时间，过期时间
        Date createDate = new Date();
        Date expireDate = new Date(createDate.getTime() + 30*60*1000);


    //token生成
    private String token(User user){
        //利用hutool创建RSA  RSA是非对称加密算法
        RSA rsa=new RSA(private_key,null);
        RSAPrivateKey rsaPrivateKey= (RSAPrivateKey) rsa.getPrivateKey();
        //JWT 登陆时根据签名信息，加密算法生成token传入前端
        JwtBuilder jwtBuilder= Jwts.builder();
        jwtBuilder.claim("username",user.getNickName())
                .setIssuedAt(createDate) //设置签发时间
                .setExpiration(expireDate)
                .setId(user.getId()+"") //设置jti,它是是JWT的唯一标识
                .signWith(rsaPrivateKey,SignatureAlgorithm.RS256); //改为RS256算法
        return jwtBuilder.compact();
    }
    /**
     * 账号密码登录验证
     * @param map
     * @return
     */
    @PostMapping(path = "/login")
    public CommonResponse login(@RequestBody Map<String,String> map){
        String phone = map.get("phone");
        String password = map.get("password");
        List<User> users = userService.loginUser(phone,password);
        Map<String,String> map1 = new HashMap<>();
        User user = new User();
        user.setId(users.get(0).getId());
        user.setNickName(users.get(0).getNickName());
        //获取tokene
        String token = token(user);
        redisTemplate.opsForValue().set("token",token,60,TimeUnit.MINUTES);
        map1.put("nickName",user.getNickName());
        map1.put("token",token);
        map1.put("extTime",expireDate.getTime()+"");
        map1.put("genTime",createDate.getTime()+"");
        return ResponseUtils.returnSuccess(map1,"登陆成功");
    }

    /**
     * 短信登录验证
     */
    //获取验证码
    @PostMapping(path = "/msg")
    public CommonResponse<String> msg(@RequestBody Map<String,String> map){
        String phone = map.get("phone");
        String key = phone;
        //从redis里判断该键是否存在
        if (redisTemplate.opsForValue().get(phone)!=null){
            throw new DmException(ErrConstant.ErrCodeConstant.ERR_PHONE_NUMBER_EXIST,ErrConstant.ErrMsgConstant.ERR_PHONE_NUMBER_EXIST);
        }
        //获取验证码
        Random random = new Random();
        int min = 1000;
        int max = 10000;
        int num = random.nextInt(max);
        while (num<min){
            random.nextInt(max);
        }
        map.put("code",num+"");
        //存入Redis验证码
        redisTemplate.opsForValue().set(phone,num+"",65, TimeUnit.SECONDS);
        //存入rabbitMQ验证码
//        rabbitTemplate.convertAndSend("dmsms",map);

        return ResponseUtils.returnSuccess(num+"","发送验证码成功60秒内有效");
    }


    //验证码登录
    @PostMapping(path = "/msg/login")
    public CommonResponse msgLogin(@RequestBody Map<String,String> map){
        String phone = map.get("phone");
        String code = map.get("vcode");

        if(code.length()!=4){
            throw new DmException(ErrConstant.ErrCodeConstant.ERR_CODE_NUMBER,ErrConstant.ErrMsgConstant.ERR_CODE_NUMBER);
        }

        String key = redisTemplate.opsForValue().get(phone);
        if(key==null){
            throw new DmException(ErrConstant.ErrCodeConstant.ERR_CODE_NUMBER_OUT,ErrConstant.ErrMsgConstant.ERR_CODE_NUMBER_OUT);
        }
        if(!key.equals(code)){
            throw new DmException(ErrConstant.ErrCodeConstant.ERR_CODE_NUMBER,ErrConstant.ErrMsgConstant.ERR_CODE_NUMBER);
        }
        List<User> users = userService.loginUser(phone);
        Map<String,String> map1 = new HashMap<>();

        User user = new User();
        user.setId(users.get(0).getId());
        user.setNickName(users.get(0).getNickName());
        //获取tokene
        String token = token(user);
        redisTemplate.opsForValue().set("token",token,60,TimeUnit.MINUTES);
        map1.put("nickName",users.get(0).getNickName());
        map1.put("token",token);
        map1.put("extTime","60");
        map1.put("genTime","150");
        //存入RabbitMQ验证码
        Map<String,String> map2 = new HashMap<>();
        map1.put("phone",phone);
        map1.put("code",code);
        return ResponseUtils.returnSuccess(map1,"登陆成功");
    }


    /**
     * 注册
     */
    @PostMapping(path = "/register")
    public CommonResponse<String> code(@RequestBody Map<String,String> map){
        String phone = map.get("phone");
        String password = map.get("password");
        String vcode = map.get("vcode");
        String key = redisTemplate.opsForValue().get(phone);
        if(key==null){
            throw new DmException(ErrConstant.ErrCodeConstant.ERR_CODE_NUMBER_OUT,ErrConstant.ErrMsgConstant.ERR_CODE_NUMBER_OUT);
        }
        if (!vcode.equals(key)){
            throw new DmException(ErrConstant.ErrCodeConstant.ERR_CODE_NUMBER,ErrConstant.ErrMsgConstant.ERR_CODE_NUMBER);
        }

        User u = new User();
        u.setPhone(phone);
        u.setPassword(password);
        userService.register(u);
        return ResponseUtils.returnSuccess(null,"注册成功");
    }

    /**
     * 局部异常处理
     */
    @ExceptionHandler(value = {DmException.class})
    public CommonResponse<String> exceptionHandler(DmException e){
        return ResponseUtils.returnFail(e);
    }

}
